﻿using ScottPlot.Avalonia;
using Digitalmes.Core.Common.Interfaces;
using Digitalmes.Core.Messages;

namespace Digitalmes.AvaloniaUI.ViewModels;

/// <summary>
/// 工作台（主页面）
/// </summary>
[VmSingletontLifeTime]
public sealed partial class WorkbenchViewModel : ViewModelBase, IDisposable
{
    private readonly CancellationTokenSource _cts = new();

    private readonly IMessageQueue<TurntableArchiveMessage> _archiveMQ;

    /// <summary>
    /// 日志消息
    /// </summary>
    [ObservableProperty]
    private ObservableCollection<string> _messageLogs = [];

    public AvaPlot PlotControl1 { get; }

    public AvaPlot PlotControl2 { get; }

    public AvaPlot PlotControl3 { get; }

    public AvaPlot PlotControl4 { get; }

    public AvaPlot PlotControl5 { get; }

    public WorkbenchViewModel(IMessageQueue<TurntableArchiveMessage> archiveMQ)
    {
        _archiveMQ = archiveMQ;

        PlotControl1 = new AvaPlot();
        PlotControl1.Plot.Font.Automatic();

        PlotControl2 = new AvaPlot();
        PlotControl2.Plot.Font.Automatic();

        PlotControl3 = new AvaPlot();
        PlotControl3.Plot.Font.Automatic();

        PlotControl4 = new AvaPlot();
        PlotControl4.Plot.Font.Automatic();

        PlotControl5 = new AvaPlot();
        PlotControl5.Plot.Font.Automatic();

        Polling();
    }

    void Polling()
    {
        var stream1 = PlotControl1.Plot.Add.DataStreamer(256);
        stream1.ViewScrollLeft();
        PlotControl1.UserInputProcessor.Disable();

        var stream2 = PlotControl2.Plot.Add.DataStreamer(256);
        stream2.ViewScrollLeft();
        PlotControl2.UserInputProcessor.Disable();

        var stream3 = PlotControl3.Plot.Add.DataStreamer(256);
        stream3.ViewScrollLeft();
        PlotControl3.UserInputProcessor.Disable();

        var stream4 = PlotControl4.Plot.Add.DataStreamer(256);
        stream4.ViewScrollLeft();
        PlotControl4.UserInputProcessor.Disable();

        var stream5 = PlotControl5.Plot.Add.DataStreamer(256);
        stream5.ViewScrollLeft();
        PlotControl5.UserInputProcessor.Disable();

        _ = Task.Run(async () =>
        {
            while (!_cts.IsCancellationRequested)
            {
                var message = await _archiveMQ.DequeueAsync().ConfigureAwait(false);
                stream1.Add(message.Speed);
                stream2.Add(message.Position);
                stream3.Add(message.ForwardRotationTime);
                stream4.Add(message.ReverseRotationTime);
                stream5.Add(message.DistanceSensor);

                // 日志显示
                AddLog(message);
            }
        });

        _ = Task.Run(async () =>
        {
            while (!_cts.IsCancellationRequested)
            {
                await Task.Delay(1_000).ConfigureAwait(false);

                if (stream1.HasNewData)
                {
                    PlotControl1.Refresh();
                    PlotControl2.Refresh();
                    PlotControl3.Refresh();
                    PlotControl4.Refresh();
                    PlotControl5.Refresh();
                }
            }
        });

        // test
        //{
        //    ScottPlot.DataGenerators.RandomWalker walker1 = new(0);
        //    //ScottPlot.DataGenerators.RandomWalker walker2 = new(1);
        //    ScottPlot.DataGenerators.RandomWalker walker3 = new(2);
        //    ScottPlot.DataGenerators.RandomWalker walker4 = new(3);
        //    ScottPlot.DataGenerators.RandomWalker walker5 = new(4);
        //    _ = Task.Run(async () =>
        //    {
        //        while (!_cts.IsCancellationRequested)
        //        {
        //            await Task.Delay(1_000).ConfigureAwait(false);

        //            await _archiveMQ.EnqueueAsync(new TurntableArchiveMessage(walker1.Next(), 1, walker3.Next(), walker4.Next(), walker5.Next())).ConfigureAwait(false);
        //        }
        //    });
        //}
    }

    private void AddLog(TurntableArchiveMessage? message)
    {
        if (message == null)
        {
            return;
        }

        if (MessageLogs.Count > 16)
        {
            MessageLogs.RemoveAt(MessageLogs.Count - 1);
        }

        var msg = $"{DateTime.Now:MM/dd HH:mm:ss}\t" +
            $"转速：{message.Speed}，" +
            $"位置：{message.Position}，" +
            $"正转时间：{message.ForwardRotationTime}，" +
            $"反转时间：{message.ReverseRotationTime}，" +
            $"测距：{message.DistanceSensor}";
        MessageLogs.Insert(0, msg);
    }

    public void Dispose()
    {
        _cts.Cancel();
    }
}
